github.com/aarzilli/tools@v0.0.0-20151123112009-0d27094f75e0/appengine/blobstore_mgt/blobstore cmd line uploader.go (about)

     1  package blobstore_mgt
     2  
     3  // http://stackoverflow.com/questions/20144066/is-it-possible-to-store-arbitrary-data-in-gae-golang-blobstore
     4  
     5  import (
     6  	"bytes"
     7  	"net/http"
     8  	"mime/multipart"
     9  
    10  	"appengine"
    11  	"appengine/blobstore"
    12  	"appengine/urlfetch"
    13  )
    14  
    15  const SampleData = `foo,bar,spam,eggs`
    16  
    17  
    18  func blobAutoUploadTest(w http.ResponseWriter, r *http.Request) {
    19  
    20  
    21  	c := appengine.NewContext(r)
    22  
    23  	// First you need to create the upload URL:
    24  	upl_url, err := blobstore.UploadURL(c, "/blob/auto-upload", nil)
    25  	if err != nil {
    26  		http.Error(w, err.Error(), http.StatusInternalServerError)
    27  		c.Errorf("%s", err)
    28  		return
    29  	}
    30  
    31  
    32  	// Now you can prepare a form that you will submit to that URL.
    33  	var b1 bytes.Buffer
    34  	fw := multipart.NewWriter(&b1)
    35  	// Do not change the form field, it must be "file"!
    36  	// You are free to change the filename though, it will be stored 
    37  	// in the BlobInfo.
    38  	file, err := fw.CreateFormFile("file", "filename-for-blobinfo-example.csv")
    39  	if err != nil {
    40  		http.Error(w, err.Error(), http.StatusInternalServerError)
    41  		c.Errorf("%s", err)
    42  		return
    43  	}
    44  	if _, err = file.Write([]byte(SampleData)); err != nil {
    45  		http.Error(w, err.Error(), http.StatusInternalServerError)
    46  		c.Errorf("%s", err)
    47  		return
    48  	}
    49  	// Don't forget to close the multipart writer.
    50  	// If you don't close it, your request will be missing the terminating boundary.
    51  	fw.Close()
    52  
    53  
    54  
    55  
    56  	// Now that you have a form, you can submit it to your handler.
    57  	req, err := http.NewRequest("POST", upl_url.String(), &b1)
    58  	if err != nil {
    59  		http.Error(w, err.Error(), http.StatusInternalServerError)
    60  		c.Errorf("%s", err)
    61  		return
    62  	}
    63  
    64  	// Don't forget to set the content type, this will contain the boundary.
    65  	req.Header.Set("Content-Type", fw.FormDataContentType())
    66  
    67  
    68  
    69  	// Now submit the request.
    70  	client := urlfetch.Client(c)
    71  	res, err := client.Do(req)
    72  	if err != nil {
    73  		http.Error(w, err.Error(), http.StatusInternalServerError)
    74  		c.Errorf("%s", err)
    75  		return
    76  	}
    77  	c.Infof("Autouploader Status - %v", res.Status)
    78  
    79  	// Check the response status, it should be whatever you return in the `/upload` handler.
    80  	if res.StatusCode != http.StatusCreated   &&   res.StatusCode != http.StatusOK{
    81  		http.Error(w, err.Error(), http.StatusInternalServerError)
    82  		c.Errorf("bad status: %s", res.Status)
    83  		return
    84  	}
    85  
    86  
    87  	// Everything went fine.
    88  	w.WriteHeader(res.StatusCode)
    89  }
    90  
    91  
    92  func blobAutoUpload(w http.ResponseWriter, r *http.Request) {
    93  
    94  	c := appengine.NewContext(r)
    95  
    96  	// Here we just checked that the upload went through as expected.
    97  	if _, _, err := blobstore.ParseUpload(r); err != nil {
    98  		http.Error(w, err.Error(), http.StatusInternalServerError)
    99  		c.Errorf("%s", err)
   100  		return
   101  	}
   102  	// Everything seems fine. Signal the other handler using the status code.
   103  	w.WriteHeader(http.StatusCreated)
   104  }	
   105  
   106  
   107  func init() {
   108  	http.HandleFunc("/blob/auto-upload-test", blobAutoUploadTest)
   109  	http.HandleFunc("/blob/auto-upload", blobAutoUpload)
   110  }